#coding=utf-8
from ansible.parsing.dataloader import DataLoader
from ansible.inventory.manager import InventoryManager
from ansible.vars.manager import VariableManager
from collections import namedtuple
from ansible.executor.playbook_executor import PlaybookExecutor
from ansible.plugins.callback import CallbackBase


loader = DataLoader()
# InventoryManager类
inventory = InventoryManager(loader=loader,sources=['demo_hosts'])
# VariableManager类
variable_manager = VariableManager(loader=loader,inventory=inventory)
# Options执行选项
Options = namedtuple('Options', ['connection','module_path', 'forks', 'timeout',  'remote_user',
                'ask_pass', 'private_key_file', 'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args',
                'scp_extra_args', 'become', 'become_method', 'become_user', 'ask_value_pass', 'verbosity',
                'check', 'listhosts', 'listtasks', 'listtags', 'syntax','diff'])
options = Options(connection='smart', module_path=None, forks=100, timeout=10,remote_user='root', 
                ask_pass=False, private_key_file=None, ssh_common_args=None, ssh_extra_args=None,sftp_extra_args=None, 
                scp_extra_args=None, become=None, become_method=None,become_user='root', ask_value_pass=False, verbosity=None, 
                check=False, listhosts=False,listtasks=False, listtags=False, syntax=False, diff=True)

class PlayBookResultsCollector(CallbackBase):
    CALLBACK_VERSION = 2.0
    """
    重写callbackBase类的部分方法
    """
    def __init__(self,*args,**kwargs):
        super(PlayBookResultsCollector,self).__init__(*args,**kwargs)
        self.task_ok={}
        self.task_failed={}    
        self.task_unreachable={}
        self.task_skipped={}
        self.task_status={}
    def v2_runner_on_ok(self,result,*args,**kwargs):
        self.task_ok[result._host.get_name()] = result
    def v2_runner_on_failed(self,result,*args,**kwargs):
        self.task_failed[result._host.get_name()] = result
    def v2_runner_on_unreachable(self,result):
        self.task_unreachable[result._host.get_name()] = result
    def v2_runner_on_skipped(self, result):
        self.task_ok[result._host.get_name()]  = result
    def v2_playbook_on_stats(self, stats):
        hosts = sorted(stats.processed.keys())
        for h in hosts:
            t = stats.summarize(h)
            self.task_status[h] = {
                                       "ok":t['ok'],
                                       "changed" : t['changed'],
                                       "unreachable":t['unreachable'],
                                       "skipped":t['skipped'],
                                       "failed":t['failures']
                                   }

callback = PlayBookResultsCollector()

# PlaybookExecutor 执行playbook
passwords = dict()
playbook = PlaybookExecutor(playbooks=['demo_book.yml'],
                    inventory = inventory,
                    variable_manager = variable_manager,
                    loader = loader,
                    options = options,
                    passwords = passwords,
                )
playbook._tqm._stdout_callback = callback
playbook.run()

results_raw = {'ok':{},'failed':{},'unreachable':{},'skipped':{},'status':{}}
for host,result in callback.task_ok.items():
    results_raw['ok'][host] = result._result
for host,result in callback.task_failed.items():
    results_raw['failed'][host] = result._result
for host,result in callback.task_unreachable.items():
    results_raw['unreachable'][host] = result._result
for host,result in callback.task_skipped.items():
    results_raw['skipped'][host] = result._result

print results_raw